var AV = require('leanengine');
var ExpressUtil = require('./expressUtility');
// var moment = require('./moment');

// 定义返回码
if (typeof ResponseCode == "undefined"){
    var ResponseCode = {};
    ResponseCode.Ok             = 1000;
    ResponseCode.APIError       = 1001;// 第三方api调用错误
    ResponseCode.ExecuteError   = 1002;// 执行失败
    ResponseCode.ObjectNotFound = 1003;// 查询的对象不存在
}

// 快递状态
if (typeof ExpressState == "undefined") {
	var ExpressState = {};
	ExpressState.none            = -1;// 没有信息
	ExpressState.onTheWay        = 0; // 在途，即货物处于运输过程中；
	ExpressState.packing		 = 1; // 揽件，货物已由快递公司揽收并且产生了第一条跟踪信息；
	ExpressState.problem         = 2; // 疑难，货物寄送过程出了问题；
	ExpressState.received        = 3; // 签收，收件人已签收；
	ExpressState.senderReceived  = 4; // 退签，即货物由于用户拒签、超区等原因退回，而且发件人已经签收；
	ExpressState.sending         = 5; // 派件，即快递正在进行同城派件；
	ExpressState.rollingBack     = 6; // 退回，货物正处于退回发件人的途中；
}

if (typeof ExpressStatePushMessage == "undefined") {
	var ExpressStatePushMessage = [ "您的快递已在运往目的地的途中", 
									"你的快递已揽件", 
									"您的快递寄运出了问题", 
									"您的快递已被签收",
									"您的快递已被发件人签收",
									"您的快递正在派送中", 
									"您的快递已退回，准备发至发件人" ];
}

// 定义表
if (typeof DataBaseTable == "undefined") {
	var DataBaseTable = {};
	DataBaseTable.finishedExpressOrderTable = "ExpressFinishedOrderInfo";// 已签收的数据表
	DataBaseTable.unFinishedExpressOrderTable = "ExpressOrderInfo";		 // 未签收的数据表
}

// 快递类型定义
if (typeof ExpressType == "undefined") {
	var ExpressType = {};
	ExpressType.shun_feng = "shunfeng";				// 顺丰速运
	ExpressType.shen_tong = "shentong";				// 申通
	ExpressType.zhong_tong = "zhongtong";			// 中通
	ExpressType.quan_feng = "quanfengkuaidi";		// 全峰
	ExpressType.kuai_jie_su_di = "kuaijiesudi";		// 快捷快递
	ExpressType.yun_da = "yunda";					// 韵达
	ExpressType.yuan_tong = "yuantong";			    // 圆通
	ExpressType.bai_shi_hui_tong = "huitongkuaidi"; // 百世汇通
	ExpressType.tian_tian = "tiantian";				// 天天快递
	ExpressType.zhai_ji_song = "zhaijisong";		// 宅急送
	ExpressType.de_bang_wu_liu = "debangwuliu";		// 德邦
}

// 申通api http://120.24.171.130:8080/StoAppPro/QueryOrderList?mailNo=3301180919024
// 中通api http://api.zto.cn/json.aspx
//        POST body:    Userid=APPLEAPP&Pwd=17DA5953C0&SrtjobNo=718859143069
// 快捷快递api(Deprecated) http://www.fastexpress.com.cn/order/getOrderStr.jsp?order_num=536013799342


// 百度api https://sp0.baidu.com/9_Q4sjW91Qh3otqbppnN2DJv/pae/channel/data/asyncqury?appid=4001&com=shunfeng&nu=912805705967
//		全峰: quanfengkuaidi  
//      快捷快递: kuaijiesudi 
//      韵达: yunda 
//      圆通: yuantong
//      百世汇通: huitongkuaidi 
//      天天快递: tiantian 
//      宅急送: zhaijisong 
//      德邦: debangwuliu




// 是否正在后台查询
var g_isCheckingExpressStatus = false;

/*
	@brief 已签收表的全局object，提供便捷方法操作
*/
var ExpressFinishedOrderInfo = AV.Object.extend(DataBaseTable.finishedExpressOrderTable, {}, {
	/* 
		@brief 根据快递单号查询是否存在，存在即返回数据，不存在返回undefined 
	*/
	expressObjectIfExist: function(expressCompany, expressNumber, callback) {
		var query = new AV.Query(ExpressFinishedOrderInfo);
		query.equalTo("express_type", expressCompany);
		query.equalTo("express_number", expressNumber);
		query.first({
			success: function(object) {
				if (object && object !== undefined) {
					console.log("[Error]: Debug code 116");
					callback(object);
				} else {
					console.log("[Warning]: Debug code 114");
					callback(undefined);
				}
			}, error: function(error) {
				console.log("[Error]: Debug code 115");
				callback(undefined);
			}
		});
	},

	/*
	    @brief 插入或者更新一条数据
	*/
	insertOrUpdateObject: function(expressCompany, expressNumber, newResult, callback) {

		var query = new AV.Query(ExpressFinishedOrderInfo);
		query.equalTo("express_type", expressCompany);
		query.equalTo("express_number", expressNumber);
		query.first({
			success: function(object) {
				if (object && object !== undefined) {
					// 存在数据，直接返回
					callback(object);
				} else {
					// 保存新数据
					var secondsSince1970 = new Date().getTime();
					var instance = new ExpressFinishedOrderInfo();
					var newValue = {"express_number": expressNumber.toString(), 
									"express_type": expressCompany.toString(), 
									"express_result": JSON.stringify(newResult), 
									"express_last_update_time": secondsSince1970.toString(),
									"express_last_data_time": newResult.routes[0].time};

					instance.save(newValue, {
						success: function(instance) {
							callback(instance);
						}, error: function(instance, error) {
							console.log("[Error]: Debug code: 105, bad: " + JSON.stringify(error));
							callback(undefined);
						}
					});
				}
			}, error: function(error) {
				console.log("[Error]: Debug code: 111, bad: " + JSON.stringify(error));
				callback(undefined);
			}
		});
	}
});

/*
	@brief 未签收表的全局object，提供接口操作
*/
var ExpressOrderInfo = AV.Object.extend(DataBaseTable.unFinishedExpressOrderTable, {}, {
	/* 
		@brief 根据快递单号查询是否存在，存在即返回数据，不存在返回undefined 
	*/
	expressObjectIfExist: function(expressCompany, expressNumber, callback) {

		var query = new AV.Query(ExpressOrderInfo);
		query.equalTo("express_type", expressCompany);
		query.equalTo("express_number", expressNumber);
		query.first({
			success: function(object) {
				if (object && object !== undefined) {
					callback(object);
				} else {
					console.log("[Warning]: Debug code 112");
					callback(undefined);
				}
			}, error: function(error) {
				console.log("[Error]: Debug code 113");
				callback(undefined);
			}
		});
	},

	/*
	    @brief 插入一条数据，支持更新操作
	    @param ifUpdate true/fase  更新/不更新
	*/
	insertOrUpdateObject: function(expressCompany, expressNumber, newResult, ifUpdate, callback) {
		var query = new AV.Query(ExpressOrderInfo);
		query.equalTo("express_type", expressCompany);
		query.equalTo("express_number", expressNumber);
		query.first({
			success: function(object) {
				var secondsSince1970 = new Date().getTime();

				if (object && object !== undefined) {

					if (!ifUpdate) {
						callback(object);
						return;
					}

					var lastDataTimeExisted = object.express_last_data_time;
					var latest_data_time = newResult.routes[0].time;
					if (lastDataTimeExisted !== latest_data_time) {
						console.log("ss");
						var newValue = { "express_last_data_time": latest_data_time,
						 				 "express_result": JSON.stringify(newResult),
						 				 "express_last_update_time": secondsSince1970.toString(),
						 				 "express_status": parseInt(newResult.deliverState)};

						object.save(newValue, {
							success: function(obj) {
								callback(obj);
							}, error: function(object, error) {
								console.log("[Error]: Debug code 109, bad: " + JSON.stringify(error));
								callback(undefined);
							}
						});
					} else {
						console.log("[Error]: Debug code 107\n lastDataTimeExisted:" + lastDataTimeExisted + " new time: " + latest_data_time);
						callback(object);
					}

				} else {
					// 保存新数据
					var instance = new ExpressOrderInfo();
					var newValue = {};
					newValue.express_number = expressNumber.toString();
					newValue.express_type = expressCompany.toString();

					if (newResult.deliverState === undefined) {
						
						newValue.express_status = ExpressState.none;
					} else {
						var state = parseInt(newResult.deliverState);
						newValue.express_result = JSON.stringify(newResult);
						newValue.express_last_update_time = secondsSince1970.toString();
						newValue.express_status = state;

						if (state !== ExpressState.none) {
							newValue.express_last_data_time = newResult.routes[0].time;
						}
					}

					instance.save(newValue, {
					  success: function(obj) {
					  		console.log("[Info]: Debug code 120");
					 		callback(obj);
					 	}, error: function(obj, error) {
					 		console.log("[Error]: Debug code 108, bad: " + JSON.stringify(error));
					 		callback(undefined);
					 	}
					});
				}
			}, error: function(error) {
				console.log("[Error]: Debug code 110, bad: " + JSON.stringify(error));
				callback(undefined);
			}
		});
	},

	/*
	    @brief 删除一条数据
	*/
	deleteObject: function(expressCompany, expressNumber, success, failure) {
		var query = new AV.Query(ExpressOrderInfo);
		query.equalTo("express_type", expressCompany);
		query.equalTo("express_number", expressNumber);
		query.first({
			success: function(object) {
				if (object && object !== undefined) {
					object.destroy({
						success: function(myObject) {
							console.log("[Info]: Delete object: " + myObject.id + "success!");
							success();
						}, error: function(myObject, error) {
							console.log("[Warning]: Delete object: " + myObject.id + "failed!");
							failure();
						}
					});
				} else {
					success();
				}
			}, error: function(error) {
				failure();
			}
		});
	},

	/*
	  @brief 查询所有数据
	*/
	queryAllObjects: function(success, failure) {
		var query = new AV.Query(ExpressOrderInfo);
		query.find({
			success: function(results) {
				success(results);
			},

			error: function(error) {
				console.log("[Error]: Debug code: 119\n" + JSON.stringify(error));
				failure();
			}
		});
	}
});

/*
  通过第三方的api查询快递
*/
function getExpressInfoByThirdParty(expressCompany, expressNumber, success, failure) {

	var urlString = ExpressUtil.expressUrlForUniversal(expressCompany, expressNumber);

	// var urlString = "https://www.kuaidi100.com/query?postid=803884706613&type=yuantong";
	// console.log("url: " + urlString);

	// AV.Cloud.httpRequest({
 //  	  url: urlString, 
 //  	  headers: {
 //  	  	'Upgrade-Insecure-Requests': 1,
 //  	  	'Cache-Control': 'max-age=0',
 //  	  	'Accept-Encoding': 'gzip, deflate, sdch'
 //  	  },
 //  	  success: function(httpResponse) {
 //  	  	console.log("http response code:" + httpResponse.status);

	//   }, 
	//   error: function(httpResponse) {
	// 	console.log(httpResponse.text + httpResponse.status);
	// 	var response = { "code": ResponseCode.APIError, "message": "查询快递失败", "debug_code": 102 };
	// 	failure(response);
 //  	  }
	// });

	AV.Cloud.httpRequest({
  	  url: urlString, 
  	  headers: {
  	  	'Cookie': 'BAIDUID=1FDE6C3743B67A6B41DAAA6CC2A801E1:FG=1'
  	  },
  	  success: function(httpResponse) {
  	  	console.log("http response code:" + httpResponse.status);
		success(ExpressUtil.expressParseForUniversal(httpResponse.text));

	  }, 
	  error: function(httpResponse) {
		console.log(httpResponse.text + httpResponse.status);
		var response = { "code": ResponseCode.APIError, "message": "查询快递失败", "debug_code": 102 };
		failure(response);
  	  }
	});
}

/*
  检查是否在支持的快递列表中
*/
function checkCompanySupportiveness(expressCompany) {
	var isCompanyOk = false;

	for (var key in ExpressType) {
	  if (ExpressType[key] === expressCompany) {
	  	isCompanyOk = true;
	  	break;
	  }
	}
	return isCompanyOk;
}

/*
客户端方法

@brief 获取快递信息
@param expressCompany 快递公司的代号
       string
@param expressNumber 快递单号
       string
*/
exports.fetchKuaiDiInfo = function (expressCompany,expressNumber,callback){
	console.log("[Info]: 查询快递开始 "+expressCompany+" "+expressNumber);

	// 更新数据到数据表
	function updateDataIntoTable(newResult) {

		var newState = newResult.deliverState;

		// 检查是否已经签收
		if (newState == ExpressState.received || newState == ExpressState.senderReceived) {

			// 添加到已签收的数据表里
			ExpressFinishedOrderInfo.insertOrUpdateObject(expressCompany, expressNumber, newResult, function(data) {
				if (data !== undefined) {
					callback(JSON.stringify({"code":ResponseCode.Ok, "result": data}));
					// 从未完成的表中删除该快递信息
					ExpressOrderInfo.deleteObject(expressCompany, expressNumber, null, null);
					// 推送消息
					exports.pushExpressUpdateInfoToUser("您的快递状态更新啦", ExpressStatePushMessage[newState], expressNumber, null);

				} else {
					callback(JSON.stringify({"code":ResponseCode.ExecuteError, "debug_code": 103 }));
				}
			});
		} else {

			// 添加到未签收的数据表里
			ExpressOrderInfo.insertOrUpdateObject(expressCompany, expressNumber, newResult, true, function(data) {
				if (data !== undefined) {
					// 推送消息
					exports.pushExpressUpdateInfoToUser("您的快递状态更新啦", ExpressStatePushMessage[newState], expressNumber, null);

					callback(JSON.stringify({"code":ResponseCode.Ok, "result": data}));
				} else {
					callback(JSON.stringify({"code":ResponseCode.ExecuteError, "debug_code": 106 }));
				}
			});
		}
	}

	// 1. 先到已签收的数据表里面查询
	ExpressFinishedOrderInfo.expressObjectIfExist(expressCompany, expressNumber, function(result) {

		if (result === undefined) {// 不存在

			console.log("[Info]: debug code: 118");
			// 2. 调用第三方api来查询快递的最新物流信息
			getExpressInfoByThirdParty(expressCompany, expressNumber, function(data){

				var jsonResult = data;
				// 3. 查询本地存储的快递的物流信息
				ExpressOrderInfo.expressObjectIfExist(expressCompany, expressNumber, function(result) {

					var shouldUpdateData = false;
		 	  		if (result && result !== undefined) {

		 	  			var last_data_time = result.express_last_data_time;
		 	  			var result_last_data_time = jsonResult.routes[0].time;

		 	  			if (last_data_time !== result_last_data_time) {
		 	  				shouldUpdateData = true;
		 	  			}

		 	  		} else {
		 	  			shouldUpdateData = true;
		 	  		}

		 	  		if (shouldUpdateData) {
		 	  			console.log("[Info]: Debug code: 117");

		 	  			if (jsonResult.deliverState === ExpressState.none) {
		 	  				console.log("[Info]: Debug code: 122");
		 	  				callback(JSON.stringify({"code": ResponseCode.Ok, "result": jsonResult}));
		 	  			} else{
		 	  				console.log("[Info]: Debug code: 121");
		 	  				// 更新到表里
		 	  				updateDataIntoTable(jsonResult);
		 	  			}

		 	  		} else {
		 	  			callback(JSON.stringify({"code": ResponseCode.Ok, "result": result}));
		 	  		}
				});
			}, function(failure) {
				callback(JSON.stringify(failure));
			});

		} else {
		
			var string = result.attributes.express_result;
			var resultJson = JSON.parse(string);
			var response = {"code": ResponseCode.Ok, "result": resultJson};
	  		callback(JSON.stringify(response));
		}
	}); 
};

exports.addExpressForTracking = function (expressCompany,expressNumber,callback) {
	var isCompanyOk = checkCompanySupportiveness(expressCompany);

	if (!isCompanyOk) {
		callback(JSON.stringify({
			code: ResponseCode.ExecuteError, 
			message: "不支持的快递公司"}));
		return;
	}

	ExpressOrderInfo.insertOrUpdateObject(expressCompany, expressNumber, {}, false, function(data) {
		if (data !== undefined) {

			callback(JSON.stringify({"code":ResponseCode.Ok, "result": data}));
		} else {
			callback(JSON.stringify({"code":ResponseCode.ExecuteError, "debug_code": 106 }));
		}
	});
};

/*
  @brief 推送  server --> client
  @param messageTitle 推送标题
  @param messageBody 推送的内容
  @param channel 指定的频道。即快递单号，订阅了该单号的用户才能收到消息。如果传空，不区分频道，所有用户都能收到。
*/
exports.pushExpressUpdateInfoToUser = function (messageTitle, messageBody, channel, callback) {
	var channels = [];
	if (channel) {
		channels = [ channel ];
	}

	AV.Push.send({
  	prod: "dev",// 开发模式
  	channels: channels,
  	data: {
    	alert: messageTitle,
    	body: messageBody
  		}
	});

	callback("Push complete.");
};

/*
  @brief 后台查询快递，定时调用
*/
exports.fetchKuaiDiInfoInBackground = function () {

	if (g_isCheckingExpressStatus === true) {
		return;
	}

	console.log("[Info]【后台】开始轮询快递信息");
	g_isCheckingExpressStatus = true;

	ExpressOrderInfo.queryAllObjects(function (resultsArray){
		for (var i = 0; i < resultsArray.length; i++) {
			var obj = resultsArray[i].toJSON();
			var expressCompany = obj.express_type;
			var expressNumber = obj.express_number;
			var lastUpdateTime = parseInt(obj.express_last_update_time);
			var secondsSince1970 = new Date().getTime();
			// 超过10分钟的可以查询
			if (secondsSince1970-lastUpdateTime > 10*60) {
				exports.fetchKuaiDiInfo(expressCompany, expressNumber, function (data) {
					console.log(data);
				});
			}
		}

		console.log("[Info]【后台】结束轮询快递信息");
		g_isCheckingExpressStatus = false;

	}, function () {
		console.log("[Warning]【后台】结束轮询快递信息");
		g_isCheckingExpressStatus = false;
	});
};

